<template>
	<div id="app">
		<el-row>
			<!--左侧容器-->
			<el-col :span="6" class="backgroundLeft">
				<search-file :title="title" :on-search="onSearch"></search-file>
				<file-list
					ref="FileList"
					:files="fileList"
					:edit-file="openItem"
					:delete-file="deleteItem"
					:reName="saveData"></file-list>

				<!--转移到快捷键-->
				<!-- <div class="btn_list">
					<button-item
						:title="'新建'"
						:btn-click="createNewFile"
						:icon="'el-icon-plus iconColor'"></button-item>
					<button-item
						:title="'导入'"
						:btn-click="importFile"
						:icon="'el-icon-download iconColor'"></button-item>
				</div> -->
			</el-col>
			<!--右侧容器-->
			<el-col :span="18" class="backgroundRight">
				<!--保存功能转移到ctrl+s-->
				<!-- <el-button type="primary" size="mini" @click="saveCurrent"
					>保存</el-button
				> -->
				<!--如果有打开的文件-->
				<template v-if="getActiveFile() !== undefined">
					<tab-list
						:files="getOpenFiles()"
						:active-item="activeId"
						:click-item="clickTabItem"
						:close-item="closeTabItem"
						:un-save-items="unSaveIds"></tab-list>
					<vue-editor
						id="editor"
						class="myEditor"
						@text-change="onTextChange"
						v-model="getActiveFile().body"></vue-editor>
				</template>
				<!--没有打开的文件-->
				<template v-else>
					<div class="init-page">新建或导入具体的文档</div>
				</template>
			</el-col>
		</el-row>
	</div>
</template>

<script>
//import initFiles from "@/renderer/utils/initFiles"
import SearchFile from "./components/SearchFile.vue"
import FileList from "./components/FileList.vue"
//import ButtonItem from "./components/ButtonItem.vue"
import TabList from "./components/TabList.vue"
import { VueEditor } from "vue2-editor/dist/vue2-editor.core"
import { v4 } from "uuid"
import {
	mapArr,
	objToArr,
	writeFile,
	renameFile,
	deleteFile,
	readFile,
} from "./utils/helper"
//导入path
const path = require("path")
//导入electron的remote模块
const { app, dialog } = require("@electron/remote")
//自定义一个当前磁盘里存放文件的路径 文档
const savePath = app.getPath("documents")
//导入electron-store
const Store = require("electron-store")
//指定文件存储的文件名
const fileStore = new Store({ name: "filesInfo" })
//导入进程通信事件监听
import useIpcRenderer from "@/renderer/hooks/useIpcRenderer"

export default {
	name: "App",
	components: {
		SearchFile,
		FileList,
		//ButtonItem,
		TabList,
		VueEditor,
	},
	data() {
		return {
			title: "我的文档",
			files: fileStore.get("files") || {}, //从持久化存储取值，没有值则返回空对象
			//当前激活的id
			activeId: "",
			//当前已打开的id
			openIds: [],
			//当前未保存的所有文件信息
			unSaveIds: [],
			//左侧查询的列表
			searchFiles: [],
		}
	},
	mounted() {
		useIpcRenderer({
			"execute-create-file": this.createNewFile,
			"execute-import-file": this.importFile,
			"execute-save-file": this.saveCurrent,
		})
	},
	methods: {
		//依据关键字收缩文件
		onSearch(val) {
			if (val !== "") {
				const newFiles = objToArr(this.files).filter(file =>
					file.title.includes(val)
				)
				this.searchFiles = newFiles
			} else {
				this.searchFiles = []
			}
		},
		editFile(id) {
			console.log(id)
		},
		//点击选项时切换选项卡
		clickTabItem(item) {
			//需要先把内容置为空，以判断修改状况

			this.activeId = item.id
		},
		//关闭选项卡
		closeTabItem(id) {
			const retOpen = this.openIds.filter(openId => openId !== id)
			this.openIds = retOpen
			//当某一选项关闭后，还需要给所有一打开文件设置一个当前状态
			if (retOpen.length > 0) {
				if (this.activeId === id) this.activeId = retOpen[0]
			} else {
				this.activeId = ""
			}
		},
		//获取当前已打开的文件信息
		getOpenFiles() {
			return this.openIds.map(openId => {
				//数组转对象后直接返回即可
				return this.files[openId]
				//return this.initFiles.find(file => file.id == openId)
			})
		},
		//获取当前激活的文件信息
		getActiveFile() {
			//return this.initFiles.find(file => file.id === this.activeId)
			return this.files[this.activeId]
		},
		//点击打开文件
		openItem(id) {
			//将当前id设置为activeId
			this.setActiveId(id)
			//点击文件时读取其内容进行显示
			if (!this.files[id].isLoaded) {
				readFile(this.files[id].path)
					.then(res => {
						this.files[id].isLoaded = true
						//添加 body 属性
						this.$set(this.files[id], "body", res)
					})
					.catch(err => {
						this.$message.error("失败:", err)
					})
			}
			if (!this.openIds.includes(id)) this.openIds = [...this.openIds, id]
		},
		setActiveId(id) {
			this.activeId = id
		},
		//文件内容改变
		onTextChange(delta) {
			//发现按下按键修改时， delta.ops.length会为2，
			if (delta.ops.length == 2)
				if (!this.unSaveIds.includes(this.activeId)) {
					this.unSaveIds.push(this.activeId)
					//内容更新后生成新的Files
				}
		},
		//删除某个文件项
		deleteItem(id) {
			const file = this.files[id]
			if (!file.isNew)
				deleteFile(file.path).then(() => {
					//使用vue方法删除一个属性
					this.$delete(this.files, id)
					// const newFiles = this.initFiles.filter(file => file.id != id)
					// this.initFiles = newFiles
					//持久化数据保存
					this.saveInfoToStore()
					//如果是已经打开的文件，也应该进行关闭
					this.closeTabItem(id)
				})
			else {
				//文件并未创建时
				this.$delete(this.files, id)
				// const newFiles = this.initFiles.filter(file => file.id != id)
				// this.initFiles = newFiles
				//如果是已经打开的文件，也应该进行关闭
				this.closeTabItem(id)
			}
		},
		//文件重命名(或新建)
		saveData(id, newTitle, isNew) {
			//检查是否重名
			const item = objToArr(this.files).find(f => f.title == newTitle)
			if (item && item.id !== id) {
				newTitle += "_copy"
			}
			const newPath = isNew
				? path.join(savePath, `${newTitle}.md`)
				: path.join(path.dirname(this.files[id].path), `${newTitle}.md`)
			//针对创新和重命名执行逻辑
			if (isNew) {
				//执行创建
				writeFile(newPath, this.files[id].body).then(() => {
					this.files[id].title = newTitle
					this.files[id].isNew = false
					this.files[id].path = newPath
					//数据持久化保存
					this.saveInfoToStore()
				})
			} else {
				//执行更新
				const oldPath = this.files[id].path
				renameFile(oldPath, newPath).then(() => {
					this.files[id].title = newTitle
					this.files[id].isNew = false
					this.files[id].path = newPath
					//数据持久化保存
					this.saveInfoToStore()
				})
			}

			// const newFiles = this.initFiles.map(file => {
			// 	if (file.id == id) {
			// 		file.title = newTitle
			// 		file.isNew = false
			// 	}
			// 	return file
			// })
			//this.initFiles = newFiles
		},
		//新建文件
		createNewFile() {
			let id = v4()
			const newFile = {
				id,
				title: "",
				isNew: true,
				body: "## 初始化内容",
				createTime: new Date().getTime(),
			}
			//避免多个新建同时出现
			let flag = objToArr(this.files).find(file => file.isNew)
			if (!flag) {
				//this.initFiles.push(newFile)
				this.$set(this.files, id, newFile)
				this.$refs.FileList.setEditItem(newFile.id)
			} else {
				this.$message.warning("尚未完成新建！")
			}
		},
		//保存当前正在编辑的文件
		saveCurrent() {
			const file = this.getActiveFile()
			writeFile(file.path, file.body).then(() => {
				//将为保存状态去掉
				this.unSaveIds = this.unSaveIds.filter(id => id !== file.id)
			})
		},
		//测试使用store
		testStore() {
			const store = new Store()
			store.set("test", "测试数据")
			console.log(store.get("test"))
			store.delete("test")
			console.log(store.get("test"))
		},
		//定义方法实现具体属性的持久化存储
		saveInfoToStore() {
			const storeObj = objToArr(this.files).reduce((ret, file) => {
				const { id, title, createTime, path } = file
				ret[id] = {
					id,
					path,
					title,
					createTime,
				}
				return ret
			}, {})
			fileStore.set("files", storeObj)
		},
		//执行文件的导入
		importFile() {
			dialog
				.showOpenDialog({
					buttonLabel: "请选择",
					title: "选择文档目录",
					properties: ["openFile", "multiSelections"],
					filters: [
						{ name: "md文档", extensions: ["md"] },
						{ name: "其他类型", extensions: ["js", "json", "vue"] },
					],
				})
				.then(ret => {
					const paths = ret.filePaths
					if (paths.length) {
						//判断当前路径们是否已存在files中，只导入不存在的
						const validPaths = paths.filter(filePath => {
							//判断当前path是否已经存在过了
							const existed = Object.values(this.files).find(file => {
								return file.path == filePath
							})
							return !existed
						})
						//将合法路径组装成file格式
						const packageData = validPaths.map(filePath => {
							return {
								id: v4(),
								title: path.basename(filePath, ".md"),
								path: filePath,
							}
						})
						//将数组数据格式处理为files所需要的
						const newFiles = { ...this.files, ...mapArr(packageData) }
						//更新数据重新渲染
						this.files = newFiles
						// TODO： 持久化数据存储

						//导入成功提示
						if (packageData.length) {
							dialog.showMessageBox({
								type: "info",
								title: "导入md文档",
								message: "文件导入成功",
							})
						}
					} else {
						this.$message.warning("未选择任何文件")
					}
				})
		},
	},
	computed: {
		//计算当前左侧列表需要展示什么信息
		fileList() {
			return this.searchFiles.length > 0
				? this.searchFiles
				: objToArr(this.files)
		},
	},
}
</script>

<style lang="less">
//引入样式
@import "~vue2-editor/dist/vue2-editor.css";
/* Quill风格 */
@import "~quill/dist/quill.core.css";
@import "~quill/dist/quill.bubble.css";
@import "~quill/dist/quill.snow.css";
.backgroundLeft {
	background-color: #7b8c7c;
	min-height: 100vh;
	margin: 0;
	position: relative;
	.btn_list {
		left: 0;
		bottom: 0;
		position: absolute;
		display: flex;
		width: 100%;
		div {
			width: 50%;
			text-align: center;
		}
		div:nth-of-type(1) {
			background-color: #8ba39e;
		}
		div:nth-of-type(2) {
			background-color: #98b4b3;
		}
	}
}
.backgroundRight {
	background-color: #c9d8cd;
	min-height: 100vh;
	margin: 0;
	.init-page {
		font: normal 28px/300px "微软雅黑";
		color: #888;
		text-align: center;
	}
}
.iconColor {
	color: white;
}
.quillWrapper {
	height: 660px !important;
}
</style>
